package com.example.finallyjob.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.example.finallyjob.dao.ActivityImp;
import com.example.finallyjob.dao.IndexImp;
import com.example.finallyjob.entity.Article;
import com.example.finallyjob.entity.FileUnit;
import com.example.finallyjob.entity.User;
import com.example.finallyjob.tool.ChangeByte;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class ArticleMake {
    Logger logger= LoggerFactory.getLogger(ArticleMake.class);
    @Autowired
    ActivityImp activityImp;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    IndexImp indexImp;


    //将文章写入磁盘、数据库
    @Transactional(rollbackFor = {SQLException.class,IOException.class})
    public String file(MultipartFile multipartFile, String title,
                       Integer user_id, String Artcle_id, String kind) throws SQLException, IOException {
        String name = UUID.randomUUID().toString();
        File file = new File(FileUnit.textUrl + name + ".txt");
        multipartFile.transferTo(file);
        Article article = new Article(user_id, title, name, new Timestamp(new Date().getTime()), kind, "text");
        int i = activityImp.upFile(article);
        JSONObject jsonObject = new JSONObject();
        if (i != 0) {
            if (Artcle_id == null || Artcle_id.equals("") || Artcle_id.equals("null")) {
                jsonObject.put(name, title);
                Query query = new Query(new Criteria("userId").is(user_id));
                Update update = new Update();
                update.set("articleId", jsonObject.toString());
                mongoTemplate.upsert(query, update, User.class);
            } else {
                Artcle_id=Artcle_id.replace("\\","");
                jsonObject = JSON.parseObject(Artcle_id);
                jsonObject.put(name, title);
                Query query = new Query(new Criteria("userId").is(user_id));
                Update update = new Update();
                update.set("articleId", jsonObject.toJSONString());
                mongoTemplate.upsert(query, update, User.class);
            }

            return jsonObject.toString();
        } else {
            return null;
        }
    }

    @ApiOperation(value = "上传文章图片、头像",notes = "返回图片文件编号")
    //上传图片进磁盘
    public String WirterImage(MultipartFile multipartFile) throws IOException {
        ChangeByte cb=new ChangeByte();
        String name=UUID.randomUUID().toString();
        String suffix=multipartFile.getOriginalFilename();
        suffix=suffix.substring(suffix.lastIndexOf("."));
        File file=new File(FileUnit.tempUrl+"temp"+name+suffix);
        multipartFile.transferTo(file);
        List<String> convert=cb.ChangePic(file,name);
        Boolean result =NewPocess(convert);
        if (result) {
            return name;
        }else {
            return null;
        }
    }

    @ApiOperation(value = "上传文章图片、头像",notes = "返回视频文件编号")
    //将视频写入磁盘
    public String WriteVideo(MultipartFile multipartFile) {
        String time = UUID.randomUUID().toString();
        String p = null;
        try {
            p = saveVideo(multipartFile, time);
            if (p != null) {
                saveVideoPic(new File(FileUnit.VideoUrl + p + ".mp4"), p);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return p;
    }


    //将视频作品信息写入数据库
    @Transactional(rollbackFor = Exception.class)
    public String insertVideo(Integer User_id, String Artcle_id,
                              String title, String num, String kind){
        Article article = new Article(User_id, title, num, new Timestamp(new Date().getTime()),kind,"video");
        int i=activityImp.upVideo(article);
        if (i>0) {
            JSONObject jsonObject = new JSONObject();
            try {
                if (Artcle_id == null || Artcle_id.equals("") || Artcle_id.equals("null") ) {
                    jsonObject.put(num, title);
                    Query query = new Query(new Criteria("userId").is(User_id));
                    Update update = new Update();
                    update.addToSet("videoId", jsonObject.toString());
                    mongoTemplate.upsert(query, update, User.class);
                    System.out.println("insert succse");
                }
                else {
                    Artcle_id=Artcle_id.replace("\\","");
                    jsonObject = JSON.parseObject(Artcle_id);
                    jsonObject.put(num, title);
                    Query query = new Query(new Criteria("userId").is(User_id));
                    Update update = new Update();
                    update.set("videoId", jsonObject.toJSONString());
                    mongoTemplate.upsert(query, update, User.class);
                    System.out.println(jsonObject.toString());
                }
                return jsonObject.toString();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println("fail");
        }
        return null;
    }

    //修改作品内容

    public Boolean UpdateArticle(MultipartFile file,String num ,
                                 String title,Integer article_id,String type) throws IOException {
        Article article=new Article();
        if(type.equals("text")){
            File file1 = new File(FileUnit.textUrl + num + ".txt");
            if(file1.exists()){
                file1.delete();
            }
            file.transferTo(file1);
            article.setArticleNum(num);
        }else {
            article.setArticleNum(num);
        }
        article.setTitle(title);
        article.setTime(new Timestamp(new Date().getTime()));
        article.setArticleId(article_id);
        article.setType(type);
        int i=activityImp.UpdateAtrcile(article);
        if(i > 0){
            return true;
        }else{
            return false;
        }
    }

    //将视频转码
    public  String saveVideo(MultipartFile multipartFile,String date) throws IOException {
        ChangeByte cb=new ChangeByte();
        if(!(new File(FileUnit.tempUrl).exists())){
            new File(FileUnit.tempUrl).mkdirs();
        }
        String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
        File file=new File(FileUnit.tempUrl+"temp"+date+suffix);
        String mark = date;
        multipartFile.transferTo(file);
        System.out.println("调用了ffmpeg.exe工具");
        List<String> convert = cb.code(file,date);
        Boolean flag=NewPocess(convert);
        if(flag) {
            return mark;
        }else {
            return null;
        }
    }

    //做视频封面
    public Boolean saveVideoPic(File file,String date) throws IOException, InterruptedException {
        System.out.println("into savevideo pIC:"+file.getPath()+date);
        ChangeByte cb=new ChangeByte();
        List<String> convert = cb.PicCode(file,date);
        boolean mark = false;
        mark=NewPocess(convert);
//        ProcessBuilder builder=new ProcessBuilder();
//        builder.command(convert);
//        builder.redirectErrorStream(true);
//        Process process=builder.start();
//        process.waitFor();
        return mark;
    }

    //调用process开始转码
    public Boolean NewPocess(List<String> convert){
        Boolean flag=false;
        try {
            ProcessBuilder builder=new ProcessBuilder();
            builder.command(convert);
            builder.redirectErrorStream(true);
            System.out.println("start");
            Process process=builder.start();
            System.out.println("end");
            String inStr = consumeInputStream(process.getInputStream());
            // 标准错误流（必须写在 waitFor 之前）
            String errStr =consumeInputStream(process.getErrorStream());
            System.out.println(inStr+errStr);
            int retCode=process.waitFor();
            if(retCode == 0){
                flag=true;
            }
        } catch (IOException | InterruptedException e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return flag;
    }

    //输出错误流
    public  String consumeInputStream(InputStream is) {
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String s ;
        StringBuilder sb = new StringBuilder();
        try {
            while((s=br.readLine())!=null){
                System.out.println(s);
                sb.append(s);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return sb.toString();
    }


    public Integer Towarning(Article articles)throws Exception{
        Article article = indexImp.selectByNum(articles);
        Integer i=Integer.parseInt(article.getException())+1;
        articles.setException(String.valueOf(i));
        return activityImp.warning(articles);
    }


    public Integer Toagree(Article articles)throws Exception{
        Article article = indexImp.selectByNum(articles);
        Integer i=article.getAgree()+1;
        System.out.println(i);
        articles.setAgree(i);
        Integer turn=activityImp.likes(articles);
        System.out.println(turn);
        articles.setAgree(i);
        return i;
    }
}
